#include "Renderer/OrthographicCameraController.h"
#include "Core/Input.h"
#include "Core/KeyCodes.h"
#include "Core/Core.h"
#include "Core/log.h"
#include "Debug/Instrumentor.h"

namespace Hazel {

    OrthographicCameraController::OrthographicCameraController(float aspecRato, bool rotation)
            : m_AspectRatio(aspecRato),
              m_Camera(-m_AspectRatio * m_ZoomLevel, m_AspectRatio * m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel),
              m_Rotation(rotation)
    {}

    void OrthographicCameraController::OnUpdate(Timestep ts) {
        HZ_PROFILE_FUNCTION();
        if (Hazel::Input::IsKeyPressed(HZ_KEY_A))
            m_CameraPosition.x -= m_CameraMoveSpeed * ts;
        else if (Hazel::Input::IsKeyPressed(HZ_KEY_D))
            m_CameraPosition.x += m_CameraMoveSpeed * ts ;

        if (Hazel::Input::IsKeyPressed(HZ_KEY_W))
            m_CameraPosition.y += m_CameraMoveSpeed * ts ;
        else if (Hazel::Input::IsKeyPressed(HZ_KEY_S))
            m_CameraPosition.y -= m_CameraMoveSpeed * ts ;

        if (m_Rotation) {
            if (Hazel::Input::IsKeyPressed(HZ_KEY_Q)){
                m_CameraRotation += m_CameraRotationSpeed * ts;
            }
            if (Hazel::Input::IsKeyPressed(HZ_KEY_E)){
                m_CameraRotation -= m_CameraRotationSpeed * ts;
            }

        }

        m_Camera.SetPosition(m_CameraPosition);
        m_Camera.SetRotation(m_CameraRotation);
        m_CameraMoveSpeed = m_ZoomLevel;
    }

    // 在OnEvent中分发MouseScrolledEvent和WindowResizeEvent事件。
    void OrthographicCameraController::OnEvent(Event &e) {
        HZ_PROFILE_FUNCTION();
        EventDispatcher dispatcher(e);
        dispatcher.Dispatch<MouseScrolledEvent>(HZ_BIND_EVENT_FN(OrthographicCameraController::OnMouseScrolled));
        dispatcher.Dispatch<WindowResizeEvent>(HZ_BIND_EVENT_FN(OrthographicCameraController::OnWindowsResized));
    }

    // OnMouseScrolled中处理鼠标滚动事件
    bool OrthographicCameraController::OnMouseScrolled(MouseScrolledEvent &e) {
        HZ_PROFILE_FUNCTION();
        // mac平台，滚轮向下滚动y-offset为正
        // 则m_ZoomLevel变小，Camera的视野变小意味着场景中的物体放大
        m_ZoomLevel -= e.GetYOffset() * 0.25;
        // m_ZomLevel最小取值为0.25，即放大倍数最大为4倍
        m_ZoomLevel = std::max(m_ZoomLevel, 0.25f);
        m_Camera.SetProjection(-m_AspectRatio * m_ZoomLevel, m_AspectRatio * m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel);
        return false;
    }

    // 实现缩放的逻辑，向上滑动放大，向下滑动缩小，最小比例限制为0.25。
    bool OrthographicCameraController::OnWindowsResized(WindowResizeEvent &e) {
        HZ_PROFILE_FUNCTION();
        // 宽高比
        m_AspectRatio = (float)e.GetWidth()/(float)e.GetHeight();
        // 简单处理
        // 相机投影的上下边界不变，宽度按窗口宽高比缩放
        m_Camera.SetProjection(-m_AspectRatio*m_ZoomLevel, m_AspectRatio*m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel);
        return false;
    }
}
